home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacWorld 1997 September
/
Macworld (1997-09).dmg
/
Shareware World
/
Utilities
/
Text Processing
/
Alpha
/
Tcl
/
Modes
/
cMode.tcl
< prev
next >
Wrap
Text File
|
1996-08-29
|
13KB
|
452 lines
# nowrap
if {$startingUp} {
addMode C dummyC { *.r } {cwarriorMenu thinkRefMenu}
addMode C++ dummyC++ {*.H *.c *.h *.cc *.cp *.cpp *.CPP *.C } { cwarriorMenu thinkRefMenu}
return
}
newModeVar C elecColon {1} 1
newModeVar C elecRBrace {1} 1
newModeVar C leftFillColumn {3} 0
newModeVar C prefixString {//} 0
newModeVar C electricSemi {1} 1
newModeVar C elecLBrace {1} 1
newModeVar C elecElse {1} 1
newModeVar C wordWrap {0} 1
newModeVar C funcExpr {^[^ \t\(#\r/@].*\(.*\)$} 0
newModeVar C parseExpr {\b([_:\w]+)\s*\(} 0
newModeVar C wordBreak {[_\w]+} 0
newModeVar C wordBreakPreface {[^_\w]} 0
newModeVar C electricTab {1} 1
newModeVar C autoMark 0 1
newModeVar C stringColor green 0
newModeVar C commentColor red 0
newModeVar C funcColor yellow 0
newModeVar C keywordColor blue 0
newModeVar C CWCompSig CWIE 0
newModeVar C CWDbgSig MWDB 0
newModeVar C SymCompSig KAHL 0
newModeVar C SymDbgSig {◊LSD} 0
set cCommentRegexp {/\*(([^*]/)|[^*]|\r)*\*/}
set cPreRegexp {^\#[\t ]*[a-z]*}
set cKeyWords {
void break register short enum extern int for if while struct static long continue
switch case char unsigned double float return else default goto do pascal Boolean
typedef volatile union auto sizeof size_t
}
if {[info exists Cwords]} {set cKeyWords [concat $cKeyWords $Cwords]}
regModeKeywords -e {//} -b {/*} {*/} -c $CmodeVars(commentColor) -f $CmodeVars(funcColor) -k $CmodeVars(keywordColor) -s $CmodeVars(stringColor) -m {#} C $cKeyWords
#================================================================================
newModeVar C++ elecColon {1} 1
newModeVar C++ elecRBrace {1} 1
newModeVar C++ leftFillColumn {3} 0
newModeVar C++ prefixString {//} 0
newModeVar C++ electricSemi {1} 1
newModeVar C++ wordBreak {[\w_]+} 0
newModeVar C++ wordBreakPreface {[^_\w]} 0
newModeVar C++ elecLBrace {1} 1
newModeVar C++ elecElse {1} 1
newModeVar C++ wordWrap {0} 1
newModeVar C++ funcExpr {^[^ \t\(#\r/@].*\(.*\)$} 0
newModeVar C++ parseExpr {\b([_:\w]+)\s*\(} 0
newModeVar C++ electricTab {1} 1
newModeVar C++ autoMark 0 1
newModeVar C++ stringColor green 0
newModeVar C++ commentColor red 0
newModeVar C++ keywordColor blue 0
newModeVar C++ funcColor yellow 0
newModeVar C++ CWCompSig CWIE 0
newModeVar C++ CWDbgSig MWDB 0
newModeVar C++ SymCompSig KAHL 0
newModeVar C++ SymDbgSig {◊LSD} 0
set {c++KeyWords} {
new delete class friend protected private public template
try catch throw operator const mutable virtual asm inline this
and and_eq bitand bitor compl not or or_eq xor xor_eq not_eq
wchar_t bool true false
static_cast dynamic_cast reinterpret_cast typeid
using namespace inherited
}
if {[info exists {C++words}]} {
set {c++KeyWords} [concat ${c++KeyWords} ${C++words} $cKeyWords]
} else {
set {c++KeyWords} [concat ${c++KeyWords} $cKeyWords]
}
regModeKeywords -e {//} -b {/*} {*/} -c [set C++modeVars(commentColor)] -f [set C++modeVars(funcColor)] -k [set C++modeVars(keywordColor)] -s [set C++modeVars(stringColor)] -m {#} {C++} ${c++KeyWords}
unset cKeyWords
unset {c++KeyWords}
#=============================================================================
# "Electric" C functions.
#=============================================================================
# returns the indent string of the line named by 'pos'
proc indentString pos {
set start [lineStart $pos]
set end [nextLineStart $pos]
set text [getText $start $end]
for {set i 0} {1} {incr i} {
set c [string index $text $i]
if {($c != "\ ") && ($c != "\t")} then {
return [string range $text 0 [expr $i-1]]
}
}
return
}
# Brace on new line, same indentation. Insert on another new line, indented in.
# First, see if we are on new line.
# if {($i == $pos) || ([lookAt $pos] == " ")} {
bind '\{' <s> electricLeft C
bind '\{' <s> electricLeft C++
# Brace on new line, immediate carriage return
bind '\}' <s> electricRight C
bind '\}' <s> electricRight C++
# Brace on new line, immediate carriage return. We don't do our electric stuff
# if we are in the middle of a for statement.
bind '\;' electricSemi C
bind '\;' electricSemi C++
proc ordSemi {} {
insertText {;}
}
bind '\;' <z> ordSemi
proc cppCR {} {
if {[lookAt [expr [getPos] - 1]] == ":"} {
if { [lookAt [getPos]] == "\r" } {
indentLine
endOfLine
carriageReturn
} else {
set pos [getPos]
endOfLine
set t [getText $pos [getPos]]
replaceText $pos [getPos] ""
indentLine
endOfLine
carriageReturn
insertText $t
}
indentLine
} else {
carriageReturn
indentLine
}
}
bind '\r' cppCR C
bind '\r' cppCR C++
#================================================================================
# proc CMarkFile {} {
# global CmodeVars
# set pos 0
# while {![catch {search -s -f 1 -r 1 -m 0 -i 0 $CmodeVars(funcExpr) $pos} res]} {
# set start [lindex $res 0]
# set end [expr [lindex $res 1] + 1]
# set text [getText $start $end]
# if {[regexp {([a-zA-Z0-9:_]+)[ \t]*\(} $text dummy word]} {
# set tmp [expr $start + [string first $word $text]]
# set inds($word) "$tmp [expr $tmp + [string length $word]]"
# }
# set pos $end
# }
# if {[info exists inds]} {
# foreach f [lsort -ignore [array names inds]] {
# set res $inds($f)
# setNamedMark $f [lineStart [lindex $res 0]] [lindex $res 0] [lindex $res 1]
# }
# }
# }
#
#
# #The previous version would not find things like void *ThisFunc( xxx ) due to the asterisk
# #I also truncated the pattern. The rest is not necessary and intrusive as far as I can tell
# proc C++MarkFile {} {
# set pos 0
# while {![catch {search -s -f 1 -r 1 -m 0 -i 0 {^([^ \t\(#\r/@].*[ \t]+)?\*?([A-Za-z0-9:~_]+)[ \t\r]*\(} $pos} res]} {
# set start [lindex $res 0]
# set end [expr [lindex $res 1] + 1]
# set thistext [getText $start $end]
# #regexp doesn't like carriage returns
# regsub -all "\r" $thistext " " thistext
# #regexp doesn't like tabs either
# regsub -all "\t" $thistext " " thistext
# #if the open paren was the last character on the line the selected text included the last carriage return as well
# #trim this off now that it is changed into a space
# set thistext [string trimright $thistext]
# if {[regexp {([a-zA-Z0-9:~_]+)[ \t]*\(} $thistext dummy word]} {
# set inds($word) [lineStart [expr $start - 1]]
# }
# set pos $end
# }
# if {[info exists inds]} {
# foreach f [lsort -ignore [array names inds]] {
# set next [nextLineStart $inds($f)]
# setNamedMark $f $inds($f) $next $next
# }
# }
# }
proc CMarkFile {} {
global CmodeVars
set pos 0
while {![catch {search -s -f 1 -r 1 -m 0 -i 0 $CmodeVars(funcExpr) $pos} res]} {
set start [lindex $res 0]
set end [expr [lindex $res 1] + 1]
set text [getText $start $end]
if {[regexp {([a-zA-Z0-9:_]+)[ \t]*\(} $text dummy word]} {
set tmp [expr $start + [string first $word $text]]
set inds($word) "$tmp [expr $tmp + [string length $word]]"
}
set pos $end
}
##
# Also mark any class or struct definitions
##
set markExpr {^(class|struct) \w+[ \t]*(:|\{)}
while {![catch {search -s -f 1 -r 1 -m 0 -i 0 "$markExpr" $pos} res]} {
set start [lindex $res 0]
set end [expr [lindex $res 1] -1]
set text [string trimright [getText $start $end] ]
set inds($text) "$start [expr $start + [string length $text]]"
set pos $end
}
if {[info exists inds]} {
foreach f [lsort -ignore [array names inds]] {
set res $inds($f)
setNamedMark $f [lineStart [lindex $res 0]] [lindex $res 0] [lindex $res 1]
}
}
}
##
# -------------------------------------------------------------------------
#
# "C++MarkFile" --
#
# Improved version which handles templates, operators etc.
# Makes use of the new mark menu in Alpha 6.2b7 which can handle
# more weird characters.
#
# -------------------------------------------------------------------------
##
proc C++MarkFile {} {
set pos 0
set markExpr {^([^ \t\(#\r/@].*[ \t]+)?\*?([A-Za-z0-9<>~_]+::[- <>A-Za-z0-9~_+=\|\*/]+|[A-Za-z0-9~_]+)[ \t\r]*\(}
while {![catch {search -s -f 1 -r 1 -m 0 -i 0 "$markExpr" $pos} res]} {
set start [lindex $res 0]
set end [expr [lindex $res 1] + 1]
set thistext [getText $start $end]
#regexp doesn't like carriage returns
regsub -all "\r" $thistext " " thistext
#regexp doesn't like tabs either
regsub -all "\t" $thistext " " thistext
#if the open paren was the last character on the line the selected text
#included the last carriage return as well
#trim this off now that it is changed into a space
set thistext [string trimright $thistext]
if {[regexp {([A-Za-z0-9<>~_]+::[- <>A-Za-z0-9~_+=\|\*/]+|[A-Za-z0-9~_]+)[ \t]*\(} $thistext dummy word]} {
if { [string first "::" $word] != -1 } {
regsub {(<\w+>)?::} $word " " it
set l [lindex $it 0]
if { $l == [lindex $it 1] } {
set word "Construct '$l'"
} elseif { "~$l" == [lindex $it 1] } {
set word "Destruct '$l'"
}
}
set inds($word) [lineStart [expr $start - 1]]
}
set pos $end
}
if {[info exists inds]} {
foreach f [lsort -ignore [array names inds]] {
set next [nextLineStart $inds($f)]
if {[string length $f] > 35} {
setNamedMark "[string range $f 0 31]..." "$inds($f)" $next $next
} else {
setNamedMark $f "$inds($f)" $next $next
}
}
}
}
proc setC++Mode {} {
changeMode "C++"
}
proc dummyC {} {}
proc dummyC++ {} {}
#===============================================================================
proc CDblClick {from to} {
global tagFile
if {[regexp {#include.*("|<)(.*)("|>)} [getText [lineStart [getPos]] [nextLineStart [getPos]]] d1 d1 inc]} {
return [cIncludeFile $inc]
}
select $from $to
set text [getSelect]
set lines [grep "^$text'" $tagFile]
if {[regexp {'(.*)'(.*[^\t])(\t)+∞} $lines dummy one two]} {
if {[string match "*$one*" [winNames -f]]} {
bringToFront $one
} else {
edit $one
}
set inds [search -f 1 -r 0 "$two" 0]
display [lindex $inds 0]
eval select $inds
} else {
launchForeAppl DanR
AEBuild {'DanR'} DanR {REF } "----" "“$text”"
}
}
proc C++DblClick {from to shift option control} {
CDblClick $from $to
}
#===============================================================================
proc cIncludeProc {menu item} {
switch $item {
open {
set text [getText [lineStart [getPos]] [nextLineStart [getPos]]]
if {[regexp {["<]([^">]*)[">]} $text dummy fname]} {
cIncludeFile $fname
}
}
addFolder { lappend cIncludePath [string trimright [get_directory] ":"]
rebuildHeaderMenu
}
removeFolder {
set item [listpick -p "Remove which folder?" [lsort $cIncludePath]]
set res [lsearch $cIncludePath $item]
set cIncludePath [lreplace $cIncludePath $res $res]
rebuildHeaderMenu
}
}
}
proc rebuildHeaderMenu {} {
global cIncludePath
eval menu -n headers -p cIncludeProc $cIncludePath
}
proc cIncludeFile {fname} {
global cIncludePath
if {[file exists "[file dir [car [winNames -f]]]:$fname"]} {
edit "[file dir [car [winNames -f]]]:$fname"
return
}
foreach path $cIncludePath {
if {[file exists "$path:$fname"]} {
edit "$path:$fname"
return
}
}
if {[askyesno "'$fname' can not be found, do you wish to add an include path?"]} {
lappend cIncludePath [string trimright [get_directory] ":"]
cIncludeFile $fname
}
}
proc getIncludeFiles {} {
global cIncludePath modeMenus mode
if {[string match "*thinkMenu*" $modeMenus($mode)]} {return [thinkGetIncludeFiles]}
set cid [scancontext create]
set lines {}
scanmatch $cid {#.*include.*(<|")(.*)(>|")} {lappend lines $matchInfo(submatch1)}
set fid [open [car [winNames -f]] "r"]
scanfile $cid $fid
close $fid
scancontext delete $cid
return [lsort -ignore $lines]
}
proc editIncludeFile {fname} {
global modeMenus mode
if {[string match "*thinkMenu*" $modeMenus($mode)]} {return [thinkEditIncludeFile $fname]}
cIncludeFile $fname
}
#===============================================================================
proc parseFuncsC {} {
global mode sortFuncsMenu
global funcExpr parseExpr
set pos 0
if $sortFuncsMenu {
while {[set res [search -s -f 1 -r 1 -i 0 -n $funcExpr $pos]] != ""} {
if {[regexp $parseExpr [getText [car $res] [cadr $res]] dummy word]} {
lappend m [list $word [car $res]]
}
set pos [cadr $res]
}
regsub -all "\[\{\}\]" [lsort -ignore $m] "" m
} else {
while {[set res [search -s -f 1 -r 1 -i 0 -n $funcExpr $pos]] != ""} {
if {[regexp $parseExpr [getText [car $res] [cadr $res]] dummy word]} {
lappend m $word [car $res]
}
set pos [cadr $res]
}
}
set files ""
foreach f [getIncludeFiles] {
lappend files $f -1
}
return [concat $files [list "(-" 0] $m]
}
proc parseFuncsC++ {} {
return [parseFuncsC]
}
#===============================================================================